package top.lunarye.api.action;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ReUtil;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import top.lunarye.api.domain.SendTaskModel;
import top.lunarye.common.domaim.TaskInfo;
import top.lunarye.common.enums.IdType;
import top.lunarye.common.enums.RespStatusEnum;
import top.lunarye.common.vo.BasicResultVO;
import top.lunarye.support.pipeline.BusinessProcess;
import top.lunarye.support.pipeline.ProcessContext;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 后置参数检查
 * @author lunar
 * @since 2022-07-11
 */
@Slf4j
@Service
public class AfterParamCheckAction implements BusinessProcess<SendTaskModel> {

    public static final String PHONE_REGEX_EXP = "^((13[0-9])|(14[5,7,9])|(15[0-3,5-9])|(166)|(17[0-9])|(18[0-9])|(19[1,8,9]))\\d{8}$";
    public static final String EMAIL_REGEX_EXP = "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$";

    public static final HashMap<Integer, String> CHANNEL_REGEX_EXP = new HashMap<>();

    static {
        CHANNEL_REGEX_EXP.put(IdType.PHONE.getCode(), PHONE_REGEX_EXP);
        CHANNEL_REGEX_EXP.put(IdType.EMAIL.getCode(), EMAIL_REGEX_EXP);
    }

    @Override
    public void process(ProcessContext<SendTaskModel> context) {
        SendTaskModel sendTaskModel = context.getProcessModel();
        List<TaskInfo> taskInfo = sendTaskModel.getTaskInfo();

        // 过滤掉不符合规则的接收者
        filterIllegalReceiver(taskInfo);
        if (CollUtil.isEmpty(taskInfo)) {
            context.setNeedBreak(true).setResponse(BasicResultVO.fail(RespStatusEnum.CLIENT_BAD_PARAMETERS));
        }
    }

    /**
     * 指定正则表达式并开始过滤
     * @param taskInfos
     */
    private void filterIllegalReceiver(List<TaskInfo> taskInfos) {
        Integer idType = CollUtil.getFirst(taskInfos.iterator()).getIdType();
        filter(taskInfos, CHANNEL_REGEX_EXP.get(idType));
    }

    /**
     * 使用正则过滤掉不符合规则的接收者
     * @param taskInfos
     * @param regexExp
     */
    private void filter(List<TaskInfo> taskInfos, String regexExp) {
        Iterator<TaskInfo> iterator = taskInfos.iterator();

        while (iterator.hasNext()) {
            TaskInfo taskInfo = iterator.next();
            Set<String> illegalAccounts = taskInfo.getReceiver().stream()
                    .filter(phone -> !ReUtil.isMatch(regexExp, phone))
                    .collect(Collectors.toSet());

            if (CollUtil.isNotEmpty(illegalAccounts)) {
                taskInfo.getReceiver().removeAll(illegalAccounts);
                log.error("messageTemplateId:{} find illegal receiver!{}", taskInfo.getMessageTemplateId(), JSON.toJSONString(illegalAccounts));
            }

            if (CollUtil.isEmpty(taskInfo.getReceiver())) {
                iterator.remove();
            }
        }
    }
}
